package com.dongbao.core.rules.java;

import com.dongbao.core.base.CodeRulesCommonBase;
import com.dongbao.core.rules.CodeRulesBase;
import com.dongbao.entity.AwardedInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiClassImpl;
import com.intellij.psi.impl.source.tree.java.PsiBinaryExpressionImpl;
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl;
import com.intellij.psi.impl.source.tree.java.PsiMethodCallExpressionImpl;
import com.intellij.psi.impl.source.tree.java.PsiPolyadicExpressionImpl;

import java.util.Arrays;
import java.util.List;

/**
 *   函数式的变量定义是否添加注释,表明意图
 *
 *   X : Integer num = names.size() + 1 ;
 *   X : Integer num4 = names.size() + 1 + 2 ;
 *   X : Integer num5 = names.size() + 1 + 2 + 3 ;
 *   X : Integer num2 = names.size();
 *   √ : Integer num3 = 10;   √
 * */
public class FunctionVariableDefineRules extends CodeRulesCommonBase implements CodeRulesBase {

    private static final Logger LOGGER = Logger.getInstance(FunctionVariableDefineRules.class);

    public FunctionVariableDefineRules(VirtualFile afterFile,PsiFile psiFile,Project project) {
        super(afterFile,psiFile,project);
        this.code = "B013";
        this.level = "B";
    }

    /**
     * 执行规则判断
     * */
    @Override
    public void run(List<AwardedInfo> deduction) {
        super.runAllExpressionRow(deduction);
    }

    @Override
    public void validDeclarationUse(PsiElement elementRow, List<AwardedInfo> deduction, PsiClassImpl psiClass, PsiMethod method){
            String text = elementRow.getText();
            PsiElement[] children = elementRow.getChildren();
            for(PsiElement variable : children){
                for(int i=0;i<variable.getChildren().length;i++){
                    PsiElement childrenVariable=variable.getChildren()[i];
                }
                /* 判断声明的变量是使用的常量还是使用的表达式或者是new的新对象 */
                if(variable.getChildren().length>5 && variable.getChildren()[5].getChildren().length>0 && "new".equals(variable.getChildren()[5].getChildren()[0].getText())){
                    /* 使用的 new 新对象方式 */
                    System.out.println("使用的 new 新对象方式 ");
                }
                if(variable.getChildren().length>=8 && variable.getChildren()[7] instanceof PsiLiteralExpressionImpl && ((PsiLiteralExpressionImpl) variable.getChildren()[7]).getType() instanceof PsiPrimitiveType){
                    /* 使用的 常量 方式*/
                    System.out.println("使用的 常量 方式");
                }
                /* 使用的 调用方法方式 方式*/
                if(variable.getChildren().length>=8 && variable.getChildren()[7] instanceof PsiMethodCallExpressionImpl){
                    /* 使用的 调用方法方式 方式 */
                    System.out.println("使用的 调用方法方式 方式");
                    /* 调用方法判断变量上面是否存在注释 */
                    checkComment(elementRow,deduction,psiClass,method,variable);
                }
                /* 使用的 组合方式 赋值*/
                if(variable.getChildren().length>=8 && variable.getChildren()[7] instanceof PsiBinaryExpressionImpl){
                    /* 使用的 组合方式 方式  Integer num = names.size() + 1 ; */
                    System.out.println("使用的 组合方式 方式");
                    /* 调用方法判断变量上面是否存在注释 */;
                    checkComment(elementRow,deduction,psiClass,method,variable);
                }
                /* 使用的 多种组合方式 赋值*/
                if(variable.getChildren().length>=8 && variable.getChildren()[7] instanceof PsiPolyadicExpressionImpl){
                    /* 使用的 组合方式 方式 Integer num4 = names.size() + 1 + 2 ; */
                    System.out.println("使用的 组合方式 方式");
                    /* 调用方法判断变量上面是否存在注释 */
                    checkComment(elementRow,deduction,psiClass,method,variable);
                }
            }
    }

    /**
     * 获取表达式上面是否存在注释 说明这个变量声明的用意
     * */
    public void checkComment(PsiElement elementRow,
                             List<AwardedInfo> deduction,
                             PsiClassImpl psiClass,
                             PsiMethod method,
                             PsiElement variable ){
        Document document = PsiDocumentManager.getInstance(psiClass.getProject()).getDocument(psiClass.getContainingFile());
            int lineNumber = document.getLineNumber(elementRow.getTextOffset());

        List<PsiElement> parentPsiElements = Arrays.asList(elementRow.getParent().getChildren());
        int curElementIndex = parentPsiElements.indexOf(elementRow);
        PsiElement lastNode = parentPsiElements.get(curElementIndex - 2);
        if(!(lastNode instanceof PsiComment)){
            /* 没有写注释 */
            packDeduction(
                    deduction,
                    psiClass.getName(),
                    psiPackageStatements.get(0).getPackageName(),
                    method.getName(),
                    "函数式的变量定义是否添加注释,表明意图",lineNumber,lineNumber);
        }
    }

    @Override
    public String describe() {
        return "命名规则";
    }
}
